package com.thd.springboottest.s3.utils;


import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.amazonaws.ClientConfiguration;
import com.amazonaws.HttpMethod;
import com.amazonaws.Protocol;
import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.client.builder.AwsClientBuilder;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3Client;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.*;

import com.thd.springboottest.s3.config.S3Config;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Date;
import java.util.UUID;
@Component
@EnableConfigurationProperties(S3Config.class)
public class S3Util {
    protected final static Logger logger = LoggerFactory.getLogger(S3Util.class);

    private static AmazonS3 createConnetion() {
//        AWSCredentials credentials = new BasicAWSCredentials(S3Config.getAccessKey(), S3Config.getSecretKey());
//        ClientConfiguration clientConfig = new ClientConfiguration();
//        clientConfig.setProtocol(Protocol.HTTP);
//        AmazonS3 conn = new AmazonS3Client(credentials, clientConfig);
//        conn.setEndpoint(S3Config.getEndpoint());
//        return conn;



        AWSCredentials credentials = new BasicAWSCredentials(S3Config.getAccessKey(), S3Config.getSecretKey());

        ClientConfiguration clientConfig = new ClientConfiguration();
        // clientConfig.setProtocol(Protocol.HTTPS);

        AmazonS3 s3Client = AmazonS3ClientBuilder.standard()
                .withCredentials(new AWSStaticCredentialsProvider(credentials))
                //设置服务器所属地区 和 申请邮件里的endPoint
                .withEndpointConfiguration(new AwsClientBuilder.EndpointConfiguration(S3Config.getEndpoint(), Regions.CN_NORTH_1.getName()))
                // 关于这里 域名加工是sdk内部的代码，加工后的域名是有问题的，所以不能让他加工，加上这个配置就不加工了
                .enablePathStyleAccess()
                .build();
        return s3Client;
    }

    public static String upload(InputStream input, String s3Path) {
        AmazonS3 conn = createConnetion();
        Bucket bucket = conn.createBucket(S3Config.getBucketName());
        s3Path = s3Path.replace("\\", "/");
        if (s3Path.indexOf(":") > 0) {
            s3Path = s3Path.substring(s3Path.indexOf(":") + 1);
        }

        if (s3Path.startsWith("/")) {
            s3Path = s3Path.substring(1);
        }

        conn.putObject(bucket.getName(), s3Path, input, new ObjectMetadata());
        return s3Path;
    }

    /**
     * @Author wuhc6
     * @Description
     * @Date  2022/10/26
     * @param input
     * @param s3Path
     * @return
     * @return java.lang.String
     **/
    public static String uploadPutObjectRequest(InputStream input, String s3Path) throws IOException {
        AmazonS3 conn = createConnetion();
        Bucket bucket = conn.createBucket(S3Config.getBucketName());
        s3Path = s3Path.replace("\\", "/");
        if (s3Path.indexOf(":") > 0) {
            s3Path = s3Path.substring(s3Path.indexOf(":") + 1);
        }

        if (s3Path.startsWith("/")) {
            s3Path = s3Path.substring(1);
        }
        PutObjectRequest request =new PutObjectRequest(bucket.getName(), s3Path, input, new ObjectMetadata());
        request.getRequestClientOptions().setReadLimit(51200000);//设置大小接近50MB
        conn.putObject(request);
        return s3Path;
    }

    public static String uploadToS3(MultipartFile file, String prefix) throws IOException {
        String fileName = file.getOriginalFilename();
        String makeFileName = UUID.randomUUID().toString().replace("-", "");
        String newFileName = makeFileName + "." + FileUtil.getPrefix(fileName);

        //s3上传附件
        String s3path = prefix + newFileName;
        String s3Result = upload(file.getInputStream(), s3path);
        //this.logger.info("S3 Upload File result:" + s3Result);
        return s3path;
    }

    public static String upload(byte[] bytes, String s3Path) {
        AmazonS3 conn = createConnetion();
        Bucket bucket = conn.createBucket(S3Config.getBucketName());
        ByteArrayInputStream input = new ByteArrayInputStream(bytes);
        s3Path = s3Path.replace("\\", "/");
        if (s3Path.indexOf(":") > 0) {
            s3Path = s3Path.substring(s3Path.indexOf(":") + 1);
        }

        if (s3Path.startsWith("/")) {
            s3Path = s3Path.substring(1);
        }

        conn.putObject(bucket.getName(), s3Path, input, new ObjectMetadata());
        return s3Path;
    }

    public static InputStream download(String s3Path) {
        s3Path = s3Path.replace("\\", "/");
        if (s3Path.indexOf(":") > 0) {
            s3Path = s3Path.substring(s3Path.indexOf(":") + 1);
        }

        if (s3Path.startsWith("/")) {
            s3Path = s3Path.substring(1);
        }

        AmazonS3 conn = createConnetion();
        Bucket bucket = conn.createBucket(S3Config.getBucketName());
        S3Object s3Object = conn.getObject(new GetObjectRequest(bucket.getName(), s3Path));
        return s3Object.getObjectContent();
    }

    public static void download(String s3Path, File localFile) {
        s3Path = s3Path.replace("\\", "/");
        if (s3Path.indexOf(":") > 0) {
            s3Path = s3Path.substring(s3Path.indexOf(":") + 1);
        }

        if (s3Path.startsWith("/")) {
            s3Path = s3Path.substring(1);
        }

        AmazonS3 conn = createConnetion();
        Bucket bucket = conn.createBucket(S3Config.getBucketName());
        conn.getObject(new GetObjectRequest(bucket.getName(), s3Path), localFile);
    }

    public static void delete(String s3Path) {
        s3Path = s3Path.replace("\\", "/");
        if (s3Path.indexOf(":") > 0) {
            s3Path = s3Path.substring(s3Path.indexOf(":") + 1);
        }

        if (s3Path.startsWith("/")) {
            s3Path = s3Path.substring(1);
        }

        AmazonS3 conn = createConnetion();
        Bucket bucket = conn.createBucket(S3Config.getBucketName());
        conn.deleteObject(bucket.getName(), s3Path);
    }

    public static String uploadWithPath(InputStream is,String fix,String path) throws Exception{
        AmazonS3 conn = createConnetion();
        Bucket bucket = conn.createBucket(S3Config.getBucketName());

        String s3FileName = FileNameUtils.createFileName("",fix);
        System.out.println(s3FileName);
        String s3Path = path + s3FileName;
        s3Path = s3Path.replace("\\", "/");
        if (s3Path.indexOf(":") > 0) {
            s3Path = s3Path.substring(s3Path.indexOf(":") + 1);
        }

        if (s3Path.startsWith("/")) {
            s3Path = s3Path.substring(1);
        }

        conn.putObject(bucket.getName(), s3Path, is, new ObjectMetadata());
        return s3Path;
    }
    public static byte[] path2ByteFile(String path){
        InputStream input = S3Util.download(path);
        byte[] byteFile = null;
        try {
            byteFile = InputStreamUtil.input2byte(input);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return byteFile;
    }

    /**
     * 按照有效时间生成代签名文件临时URL
     * @param s3Path
     * @param hour
     * @return
     */
    public static String generateUrl(String s3Path,int hour) {
        s3Path = s3Path.replace("\\", "/");
        if (s3Path.indexOf(":") > 0) {
            s3Path = s3Path.substring(s3Path.indexOf(":") + 1);
        }

        if (s3Path.startsWith("/")) {
            s3Path = s3Path.substring(1);
        }
        AmazonS3 conn = createConnetion();
        DateTime expiration = DateUtil.offset(new Date(), DateField.HOUR, 1);
        if(hour != 0){
            expiration = DateUtil.offset(new Date(), DateField.HOUR, hour);
        }

        GeneratePresignedUrlRequest request = new GeneratePresignedUrlRequest(S3Config.getBucketName(),s3Path).withExpiration(expiration);
        String generateUrl = conn.generatePresignedUrl(request).toString();
        logger.info("文件临时URL:{}",generateUrl);
        return generateUrl;
    }
}